Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to sanitize annotation inputs #7874

Merged
merged 3 commits into from
Nov 12, 2021

Conversation

rikatz
Copy link
Contributor

@rikatz rikatz commented Nov 2, 2021

This PR adds two new items in ConfigMap:

  • annotation-value-word-blocklist

Based on this, Ingress will drop objects that contians annotations with those words or chars. I'm still thinking about dropping the chars and keeping only the word validation (as chars are just words with 1 character...)

TODO:

  • Docs
  • e2e test for webhook
  • Deciding if we should drop the char validation

@k8s-ci-robot k8s-ci-robot added cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. needs-kind Indicates a PR lacks a `kind/foo` label and requires one. needs-priority size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Nov 2, 2021
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: rikatz

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Nov 2, 2021
@@ -754,6 +762,9 @@ func NewDefault() Configuration {
defNginxStatusIpv6Whitelist := make([]string, 0)
defResponseHeaders := make([]string, 0)

defAnnotationValueWordBlocklist := []string{"load_module", "lua_package", "_by_lua", "location", "root"}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we add others like token etc?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you are fast uh! haha! Yeah, this list should be updated I guess. I tried to add the dangerous ones!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So what list do you think it's good to have here? When you say token, you say like the whole "/var/run/..." for the serviceaccount?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would also add probably proxy_pass directives, so someone cannot bypass the internal balancer for the evil :D

Copy link
Contributor

@iamNoah1 iamNoah1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one little remark :)

}
firstIngress := framework.NewSingleIngress("first-ingress", "/", host, f.Namespace, framework.EchoService, 80, annotations)
_, err := f.KubeClientSet.NetworkingV1().Ingresses(f.Namespace).Create(context.TODO(), firstIngress, metav1.CreateOptions{})
assert.NotNil(ginkgo.GinkgoT(), err, "creating an ingress with invalid annotation value should return an error")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense to check if the correct err (message) is thrown?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hum, I think we can do that yes. I would leave this anyway as a followup for some issue (feel free to open it!) to improve e2e tests in a sense that we not only verify if the error is not nil, but if error is what we expect (in all tests).

This can become a good first issue, wdyt?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good Idea, I will open one :)

@iamNoah1
Copy link
Contributor

iamNoah1 commented Nov 8, 2021

Just saw one comment that might be related to this PR: kubernetes/kubernetes#126811. Just in case you missed it @rikatz

if parser.AnnotationsPrefix != parser.DefaultAnnotationsPrefix {
if strings.HasPrefix(key, fmt.Sprintf("%s/", parser.DefaultAnnotationsPrefix)) {
return fmt.Errorf("This deployment has a custom annotation prefix defined. Use '%s' instead of '%s'", parser.AnnotationsPrefix, parser.DefaultAnnotationsPrefix)
}
}
if strings.HasPrefix(key, fmt.Sprintf("%s/", parser.AnnotationsPrefix)) {
for _, forbiddenvalue := range arraybadWords {
if strings.Contains(value, forbiddenvalue) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My only thought is if we need to run strings.TrimSpace every element as well, I’m afraid Contains may fail otherwise.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you give me one example? not following here (rainy day, a bit sleepy... :) )

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@theunrealgeek GOOD CATCH!!! Thanks! I will quickly fix this and also add some regression / e2e test before releasing!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But now I see that I do trimming a bit upper:

arraybadWords := strings.Split(strings.TrimSpace(cfg.AnnotationValueWordBlocklist), ",")

Don't this solve the problem?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rikatz

arraybadWords := strings.Split(strings.TrimSpace(cfg.AnnotationValueWordBlocklist), ",")

will only trim space at the beginning and end of the annotation value, but not in between elements that may exist around the commas which is what my example in the Go playground is pointing out.

In the default value this won’t be a problem since you are coming the CSV with a Join on the list, but for user overridden ones it will be hard to enforce that they don’t put spaces between the commas to make things more readable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, I see :) I was in my head thinking that trimSpace works for all the array, not only beginning and ending and you are right :)

Weirdly, when adding this to unit_test it passes as well, will have to check it better.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anyway, PTAL here: #7921

t: t,
err: nil,
}
ing.ObjectMeta.Annotations["nginx.ingress.kubernetes.io/custom-headers"] = "invalid_directive"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With context of my previous comment, checking for another_directive would also perhaps be useful.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/kubernetes/ingress-nginx/pull/7921/files

Added here just to make sure it's working fine :)

@@ -754,6 +760,20 @@ func NewDefault() Configuration {
defNginxStatusIpv6Whitelist := make([]string, 0)
defResponseHeaders := make([]string, 0)

defAnnotationValueWordBlocklist := []string{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we allow users to override the default value? Or should it be appended?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They can override. Appending IMO is bad, as the idea of overriding is actually removing something that may be problematic for them (like, if you use mod_security directives you want to remove {} from the list)

@strongjz
Copy link
Member

strongjz commented Nov 9, 2021

/kind feature
/priority critical-urgent
/triage accepted
;)

@k8s-ci-robot k8s-ci-robot added kind/feature Categorizes issue or PR as related to a new feature. priority/critical-urgent Highest priority. Must be actively worked on as someone's top priority right now. triage/accepted Indicates an issue or PR is ready to be actively worked on. and removed needs-kind Indicates a PR lacks a `kind/foo` label and requires one. needs-priority needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. labels Nov 9, 2021
@rikatz rikatz added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Nov 12, 2021
@rikatz rikatz added this to the v1.0.5 milestone Nov 12, 2021
@k8s-ci-robot k8s-ci-robot merged commit 67e13bf into kubernetes:main Nov 12, 2021
rikatz added a commit to rikatz/ingress-nginx that referenced this pull request Nov 16, 2021
* Add option to sanitize annotation inputs

* Fix e2e tests after string sanitization

* Add proxy_pass and serviceaccount as denied values
k8s-ci-robot pushed a commit that referenced this pull request Nov 16, 2021
* fix: fix thread synchronization issue #6245 (#7800)

* Add option to sanitize annotation inputs (#7874)

* Add option to sanitize annotation inputs

* Fix e2e tests after string sanitization

* Add proxy_pass and serviceaccount as denied values

* Trim spaces from badword items (#7921)

* Fix tests from cherrypick

Co-authored-by: Jens Reimann <ctron@dentrassi.de>
rchshld pushed a commit to joomcode/ingress-nginx that referenced this pull request May 19, 2023
* Add option to sanitize annotation inputs

* Fix e2e tests after string sanitization

* Add proxy_pass and serviceaccount as denied values
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. kind/feature Categorizes issue or PR as related to a new feature. lgtm "Looks good to me", indicates that a PR is ready to be merged. priority/critical-urgent Highest priority. Must be actively worked on as someone's top priority right now. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. triage/accepted Indicates an issue or PR is ready to be actively worked on.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants